package com.example.demo.service.aiService;

import com.example.demo.demo.invoke.DialogueState;
import com.example.demo.enums.CombinedAiResponseV2;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.stereotype.Service;

@Service
public class UnifiedAiService {

    private final ChatClient chatClient;
    private final ObjectMapper objectMapper;

    // --- vvv 这是V3版的“强制思考”超级提示词模板 vvv ---
    private static final String UNIFIED_PROMPT_TEMPLATE_V3 = """
            ### System Role & Instructions ###
            You are "恋爱大师", a world-class empathetic AI relationship advisor. Your goal is to help users by understanding their situation through conversation.
            Your final output **MUST BE a single, valid JSON object**.

            ### Your Internal Thought Process (Chain-of-Thought) ###
            For each user message, you MUST follow these three internal steps. You will write down your conclusions for each step in the "thinking" field of the output JSON.

            **Step 1: Update State.**
            Analyze the `Current Dialogue State` and the `User's Latest Message`. Synthesize all information to create an `updatedState`.

            **Step 2: Assess Sufficiency.**
            Look at the `updatedState` you just created. Answer this question with a "Yes" or "No": Is there enough information (e.g., a clear event, involved people, and a potential reason) to give a comprehensive, final piece of advice?

            **Step 3: Decide Action.**
            Based on your "Yes/No" answer from Step 2, state your chosen action. The only valid actions are `ASK_A_CLARIFYING_QUESTION` or `PROVIDE_FINAL_ADVICE`.

            ### Your Final Response Generation ###
            After completing your thought process, generate the `replyToUser` field based on your chosen action:
            - If your chosen action was `ASK_A_CLARIFYING_QUESTION`: The `replyToUser` MUST be a single, warm, empathetic, open-ended question to gather more details. DO NOT give any analysis or advice.
            - If your chosen action was `PROVIDE_FINAL_ADVICE`: The `replyToUser` MUST be a full, structured response following the three-part format: 【心理分析】, 【行动建议】, 【话术参考】.

            ### Context for this Turn ###
            **Current Dialogue State (JSON):**
            {currentStateJson}
                    
            **User's Latest Message:**
            "{latestQuery}"

            ### Your Task ###
            Now, execute your internal thought process and generate the final response. Your entire output must be a single JSON object matching this exact format:
            ```json
            \\{
              "thinking": "Step 1: [Your summary of the updated state]. Step 2: [Your Yes/No assessment]. Step 3: [Your chosen action].",
              "updatedState": \\{
                "userGoal": "...",
                "accumulatedSlots": \\{ "key1": "value1" \\}
              \\},
              "replyToUser": "..."
            \\}
            ```
            """;
    // --- ^^^ V3提示词模板结束 ^^^ ---

    public UnifiedAiService(ChatClient.Builder chatClientBuilder, ObjectMapper objectMapper) {
        // 初始化基于内存的对话记忆
        MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
                .chatMemoryRepository(new InMemoryChatMemoryRepository())
                .maxMessages(10)
                .build();
        this.chatClient = chatClientBuilder
                .defaultAdvisors(
                        MessageChatMemoryAdvisor.builder(chatMemory).build()
                )
                .build();
        this.objectMapper = objectMapper;
    }

    // 注意：方法的返回值类型已改为 CombinedAiResponseV2
    public CombinedAiResponseV2 processTurn(DialogueState currentState, String latestQuery) {
        String currentStateJson = convertStateToJson(currentState);

        return this.chatClient.prompt()
                .advisors(advisor -> advisor.param("chat_memory_conversation_id", "678")
                        .param("chat_memory_response_size", 100))
                .user(userSpec -> userSpec
                        .text(UNIFIED_PROMPT_TEMPLATE_V3) // 使用V3模板
                        .param("currentStateJson", currentStateJson)
                        .param("latestQuery", latestQuery)
                )
                .call()
                .entity(CombinedAiResponseV2.class); // 期望返回新的DTO类型
    }

    private String convertStateToJson(DialogueState state) {
        try {
            return objectMapper.writeValueAsString(state);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Error serializing DialogueState to JSON", e);
        }
    }
}